#! python3
# 下载所有 XKCD 漫画

import requests
import bs4
import os
import logging

from urllib import request

logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')


def fun(blockNum, blockSize, totalSize):
    """
    blocknum:当前的块编号
    blocksize:每次传输的块大小
    totalsize:网页文件总大小
    """
    downSIZE = blockNum * blockSize / 1024 / 1024
    totalSIZE = totalSize / 1024 / 1024
    percent = downSIZE / totalSIZE
    if percent > 1.0:
        percent = 1.0
    percent = percent * 100
    print("[%.2fM/%.2fM]\t%.2f%%" % (downSIZE, totalSIZE, percent))


try:

    path = 'F:/download/XkcdPicture'
    # 创建漫画保存目录
    if not os.path.exists(path):
        os.mkdir(path)

    # 该地址为第一页漫画的地址
    BASE_URL = "https://xkcd.in/"
    url = BASE_URL
    # url = 'https://xkcd.in/comic?lg=cn&id=16'

    i = 1
    while True:
        logging.debug("=========================================================================")
        logging.debug("开始用requests获取第" + str(i) + "页的漫画，地址为：" + url)
        res = requests.get(url)
        res.raise_for_status()
        res.encoding = 'utf-8'
        # print(res.text)

        logging.debug("开始解析 HTML ===================")
        soup = bs4.BeautifulSoup(res.text, features="html.parser")

        logging.debug("开始获取图片信息===================")
        elementsPic = soup.select('.comic-body>a>img')  # class属性为comic-body下的<a>元素下的<img>元素
        elementPic = elementsPic[0]
        fileName = "{0}-{1}.jpg".format(str(i), elementPic.get('title')).replace('/', '-')
        picUrl = BASE_URL + elementPic.get('src')

        logging.debug("开始下载本页的漫画[" + fileName + "]===================")
        #  下载方法一
        # resPic = requests.get(picUrl)
        # resPic.raise_for_status()
        # file = open(os.path.join(path, fileName), 'wb')
        # for text in resPic.iter_content(100000):
        #     file.write(text)
        # file.close()

        #  下载方法二
        """
        函数：urllib.urlretrieve(url[, filename[, reporthook[, data]]]) 
        参数说明： 
        url：外部或者本地url ,url中不要含有中文，好像会出错。
        filename：指定了保存到本地的路径； 
        reporthook：是一个回调函数，当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。 
        data：指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers)，filename表示保存到本地的路径，header表示服务器的响应头。 
        """
        request.urlretrieve(picUrl, os.path.join(path, fileName), fun)

        logging.debug("开始取下一页漫画的地址===================")
        elementsNext = soup.select('.nextLink>a')  # class属性为nextLink下的<a>元素
        if len(elementsNext) == 0:
            logging.debug("本页漫画下载完成，这是最后一页")
            break
        else:
            elementNext = elementsNext[0]
            nextUrl = elementNext.get('href')
            url = BASE_URL + nextUrl
            logging.debug("本页漫画下载完成，下一页地址为[" + nextUrl + "]===================")

        i += 1

except Exception as e:
    # print('there have a error : ' + e)
    logging.debug('there have a error : ' + e)
